package com.xinggq.pay.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinggq.pay.service.entity.CallbackRetryLogEntity;
import com.xinggq.pay.service.mapper.CallbackRetryLogMapper;
import com.xinggq.pay.service.service.CallbackRetryLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 回调重试日志服务实现类
 * @author xinggq
 * @since 2025/9/16
 */
@Slf4j
@Service
public class CallbackRetryLogServiceImpl extends
    ServiceImpl<CallbackRetryLogMapper, CallbackRetryLogEntity> implements CallbackRetryLogService {

  @Override
  public void saveCallbackLog(CallbackRetryLogEntity logEntity) {
    if (logEntity == null) {
      throw new IllegalArgumentException("回调日志实体不能为空");
    }
    this.save(logEntity);
  }


  @Override
  public List<CallbackRetryLogEntity> findRetryRecords(LocalDateTime currentTime,
      int maxRetryCount) {
    LambdaQueryWrapper<CallbackRetryLogEntity> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper
        // 失败状态
        .eq(CallbackRetryLogEntity::getCallbackStatus, 0)
        // 未达到最大重试次数
        .lt(CallbackRetryLogEntity::getCallCount, maxRetryCount)
        // 到达重试时间
        .le(CallbackRetryLogEntity::getNextRetryTime, currentTime)
        .orderByAsc(CallbackRetryLogEntity::getNextRetryTime)
        // 每次50条
        .last(" LIMIT 50");
    return this.list(queryWrapper);
  }

  @Override
  public void updateRetryRecord(Long id, String responseData, Integer callbackStatus,
      LocalDateTime nextRetryTime) {
    if (id == null) {
      throw new IllegalArgumentException("记录ID不能为空");
    }
    LambdaUpdateWrapper<CallbackRetryLogEntity> updateWrapper = new LambdaUpdateWrapper<>();
    updateWrapper.eq(CallbackRetryLogEntity::getId, id)
        .set(CallbackRetryLogEntity::getResponseData, responseData)
        .set(CallbackRetryLogEntity::getCallbackStatus, callbackStatus)
        .set(CallbackRetryLogEntity::getNextRetryTime, nextRetryTime)
        // 重试次数加1
        .setSql("call_count = call_count + 1");
    this.update(updateWrapper);
  }

  @Override
  public CallbackRetryLogEntity findLatestByTradeNo(String tradeNo) {
    LambdaQueryWrapper<CallbackRetryLogEntity> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(CallbackRetryLogEntity::getTradeNo, tradeNo)
        .orderByDesc(CallbackRetryLogEntity::getUpdateTime)
        .last("LIMIT 1");
    return this.getOne(queryWrapper);
  }

}